﻿#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SpaceGame.Gameplay.AI.Behaviors;
using SpaceGame.Gameplay.AI.Pathfinding;
using System.Linq;
#endregion

namespace SpaceGame.Gameplay.AI
{
    /// <summary>
    /// Class responsible for managing AI controlled ship.
    /// </summary>
    public class BotShip : Ship
    {
        /// <summary>
        /// Path manager.
        /// </summary>
        private readonly PathPlanner pathPlanner;

        /// <summary>
        /// Steering behaviors.
        /// </summary>
        private readonly SteeringBehavior steering;

        /// <summary>
        /// Behavior responsible for searching for weapons.
        /// </summary>
        private readonly ArmorBehavior armor;

        /// <summary>
        /// Behavior responsible for seeking enemy and attacking.
        /// </summary>
        private readonly AttackBehavior attack;
        

        #region Constructor
        public BotShip(World world, Color color)
            : base(world, color)
        {
            pathPlanner = new PathPlanner(this, world);
            steering = new SteeringBehavior(this);
            armor = new ArmorBehavior(this);
            attack = new AttackBehavior(this);
        }
        #endregion

        public override void CaptureInput(float elapsedTime)
        {
            if (!Playing)
            {
                input.TriedJoined = true;
            }

            
            #region Decide where to go
            Vector2? desiredPosition = null;

            if (armor.CheckForPowerUps())
            {
                desiredPosition = armor.PowerUpLocation.Value;
            }

            if (attack.CheckForNearestEnemy())
            {
                if (!desiredPosition.HasValue || attack.IsEnemyClose)
                {
                    desiredPosition = attack.NearestEnemy.Position;
                }
            }

            if (desiredPosition.HasValue)
            {
                if (!pathPlanner.IsGoalDefined || pathPlanner.Goal != desiredPosition)
                    pathPlanner.SetGoal(desiredPosition.Value);
            } 
            else
            {
                pathPlanner.CancelGoal();
            }
            #endregion

            #region tell pathplanner where to go
            if (pathPlanner.IsGoalDefined)
            {
                var target = pathPlanner.GetSubGoal();
                var direction = target - Position;
                direction.Normalize();

                input.LeftStick = direction;

                //todo: steer to arrival at goal to make it smoother (or use splines)
                input.LeftStick += steering.Arrival(target, input.LeftStick);
                //if (random.Next(10) < 4) input.LeftStick /= 3;
            }
            #endregion

            #region avoid obstacles
            
            var avoidance = steering.AvoidObstacles(input.LeftStick);
            input.LeftStick += avoidance;
            #endregion

            

            #region decide where to fire
            if (attack.CheckForVisibleEnemy())
            {
                //fire it away
                input.RightStick = attack.AimAtVisibleEnemy;
            }
            #endregion


            //panic
            if (life < 5)
            {
                input.MineFired = true;
            }

        }
        
          public override void Draw(float elapsedTime, LineBatch lineBatch)
          {
              /*
              var forward = new_direction;
              forward.Normalize();

              var head_radar = forward * 50f;
              head_radar.X += Position.X;
              head_radar.Y += Position.Y;

              lineBatch.DrawLine(Position, head_radar, Color.WhiteSmoke);
               */

              base.Draw(elapsedTime, lineBatch);
          }
        

        







    }
}
